package cn.psvmc.cxzapi.service.customer;

import cn.psvmc.cxzapi.config.mybatisplus.service.impl.AbstractService;
import cn.psvmc.cxzapi.constant.GlobalConstant;
import cn.psvmc.cxzapi.exception.ServiceException;
import cn.psvmc.cxzapi.mapper.customer.TCustomerCouponMapper;
import cn.psvmc.cxzapi.mapper.store.TCouponCustomerMapper;
import cn.psvmc.cxzapi.mapper.store.TCouponMapper;
import cn.psvmc.cxzapi.model.common.SearchEntity;
import cn.psvmc.cxzapi.model.customer.TCustomerCoupon;
import cn.psvmc.cxzapi.model.customer.TCustomerCouponVo;
import cn.psvmc.cxzapi.model.store.TCoupon;
import cn.psvmc.cxzapi.service.system.ServiceUtil;
import cn.psvmc.cxzapi.util.ToolUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 客户优惠券表 服务实现类
 * @Author auto
 * @Date 2024-08-15
 */
@Service
public class TCustomerCouponService extends AbstractService<TCustomerCouponMapper, TCustomerCoupon> {

    @Resource
    private TCustomerCouponMapper tCustomerCouponMapper;
    @Resource
    private TCouponMapper tCouponMapper;
    @Resource
    private TCouponCustomerMapper couponCustomMapper;
    @Resource
    private HttpServletRequest request;
    //读写锁（多个线程可以同时持有读锁，但只能有一个线程持有写锁。适用于读多写少的场景）
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    @Resource
    private ServiceUtil serviceUtil;

    /**
     * @Description 领券
     * @Date 2024/8/15 15:49
     * @Author YWX
     * @Param [tCustomCoupon]
     * @Return void
     **/
    public void add(TCoupon coupon) {
        Integer customerId = serviceUtil.getCustomerId();
        TCustomerCoupon tCustomerCoupon = new TCustomerCoupon();
        tCustomerCoupon.setCouponid(coupon.getCouponid());
        tCustomerCoupon.setCustomerid(customerId);
        saveCustomerCoupon(tCustomerCoupon);//保存领券信息
    }

    //保存领券信息
    private void saveCustomerCoupon(TCustomerCoupon tCustomerCoupon) {
        Integer couponid = tCustomerCoupon.getCouponid();
        TCoupon tCoupon;
        rwLock.readLock().lock();
        try {
            //读取数据
            if (ToolUtils.isTrueInteger(couponid)) {
                tCoupon = tCouponMapper.selectById(couponid);
            } else {
                tCoupon = tCouponMapper.selectByCode(tCustomerCoupon.getCouponCode());//根据优惠券编码查询优惠券
                tCustomerCoupon.setCouponid(tCoupon.getCouponid());
            }
            if (tCoupon == null || tCoupon.getDeleted().equals(1) || !tCoupon.getCouponStatus().equals(1)) {
                throw new ServiceException("优惠券已失效！");
            }
            TCustomerCouponVo vo = tCustomerCouponMapper.getNumById(tCustomerCoupon);
            if (!vo.getUsableNum().equals(0)) {
                throw new ServiceException("请使用后在领取新的券！");
            }
            if (tCoupon.getLimitNum().compareTo(vo.getTotalNum()) <= 0) {
                throw new ServiceException("已超过领取次数限制！");
            }
            if (tCoupon.getUseNum().equals(0)) {
                throw new ServiceException("优惠券已抢完！");
            }
            if (tCoupon.getUserScope().equals(2)) {//指定用户
                Integer num = couponCustomMapper.getNumById(tCustomerCoupon);//客户是否有权限领券
                if (num.equals(0)) {
                    throw new ServiceException("没有领取权限！");
                }
            }
        } finally {
            rwLock.readLock().unlock();
        }

        rwLock.writeLock().lock();
        try {
            //修改数据
            LocalDateTime begin;
            LocalDateTime end;
            if (tCoupon.getLimitType().equals(1)) {//相对期限
                begin = LocalDateTime.now();
                end = begin.plusDays(tCoupon.getLimitDay());
            } else {
                begin = tCoupon.getUseTimeBegin();
                end = tCoupon.getUseTimeEnd();
            }
            tCustomerCoupon.setBeginDate(begin);
            tCustomerCoupon.setEndDate(end);
            tCustomerCouponMapper.insert(tCustomerCoupon);
            tCouponMapper.updateUseNum(couponid);//更新优惠券可用数量
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    /**
     * @Description 领券中心
     * @Date 2024/8/15 17:24
     * @Author YWX
     * @Param [iPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map>
     **/
    public IPage<Map> list(Page<TCustomerCoupon> iPage, SearchEntity entity) {
        checkCustomId(entity);//检查客户id
        return tCustomerCouponMapper.listAll(iPage, entity);
    }

    //检查客户id
    private void checkCustomId(SearchEntity entity) {
        int customid = request.getIntHeader(GlobalConstant.USRID);
        if (!ToolUtils.isTrueInteger(customid)) {
            throw new ServiceException("客户id不能为空！");
        }
        entity.setCustomerid(customid);
    }

    /**
     * @Description 我的优惠券列表
     * @Date 2024/8/15 17:26
     * @Author YWX
     * @Param [iPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map>
     **/
    public IPage<Map> listMy(Page<TCustomerCoupon> iPage, SearchEntity entity){
        checkCustomId(entity);//检查客户id
        return tCustomerCouponMapper.listMy(iPage, entity);
    }

    /**
     * @Description 使用券码领券
     * @Date 2024/9/1 10:53
     * @Author YWX
     * @Param [coupon]
     * @Return void
     **/
    public void add2(TCoupon coupon) {
        Integer customerId = serviceUtil.getCustomerId();
        TCustomerCoupon tCustomerCoupon = new TCustomerCoupon();
        tCustomerCoupon.setCouponCode(coupon.getCouponCode());
        tCustomerCoupon.setCustomerid(customerId);
        saveCustomerCoupon(tCustomerCoupon);//保存领券信息
    }
}
